{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "%config InlineBackend.figure_format = 'retina'\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import torch\n",
    "from torch import nn\n",
    "from torch import optim\n",
    "import torch.nn.functional as F\n",
    "from torchvision import datasets, transforms, models"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Most of the pretrained models require the input to be 224x224 images. Also, we'll need to match the normalization used when the models were trained. Each color channel was normalized separately, the means are `[0.485, 0.456, 0.406]` and the standard deviations are `[0.229, 0.224, 0.225]`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_dir = 'Cat_Dog_data'\n",
    "\n",
    "# TODO: Define transforms for the training data and testing data\n",
    "train_transforms = transforms.Compose([transforms.RandomRotation(30),\n",
    "                                       transforms.RandomResizedCrop(224),\n",
    "                                       transforms.RandomHorizontalFlip(),\n",
    "                                       transforms.ToTensor(),\n",
    "                                       transforms.Normalize([0.485, 0.456, 0.406],\n",
    "                                                            [0.229, 0.224, 0.225])])\n",
    "\n",
    "test_transforms = transforms.Compose([transforms.Resize(255),\n",
    "                                      transforms.CenterCrop(224),\n",
    "                                      transforms.ToTensor(),\n",
    "                                      transforms.Normalize([0.485, 0.456, 0.406],\n",
    "                                                           [0.229, 0.224, 0.225])])\n",
    "\n",
    "# Pass transforms in here, then run the next cell to see how the transforms look\n",
    "train_data = datasets.ImageFolder(data_dir + '/train', transform=train_transforms)\n",
    "test_data = datasets.ImageFolder(data_dir + '/test', transform=test_transforms)\n",
    "\n",
    "trainloader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)\n",
    "testloader = torch.utils.data.DataLoader(test_data, batch_size=64)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can load in a model such as [DenseNet](http://pytorch.org/docs/0.3.0/torchvision/models.html#id5). Let's print out the model architecture so we can see what's going on."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/lib/python3.6/site-packages/torchvision-0.2.1-py3.6.egg/torchvision/models/densenet.py:212: UserWarning: nn.init.kaiming_normal is now deprecated in favor of nn.init.kaiming_normal_.\n",
      "Downloading: \"https://download.pytorch.org/models/densenet121-a639ec97.pth\" to /root/.torch/models/densenet121-a639ec97.pth\n",
      "100%|██████████| 32342954/32342954 [00:01<00:00, 17098394.33it/s]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "DenseNet(\n",
       "  (features): Sequential(\n",
       "    (conv0): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n",
       "    (norm0): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (relu0): ReLU(inplace)\n",
       "    (pool0): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)\n",
       "    (denseblock1): _DenseBlock(\n",
       "      (denselayer1): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(64, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer2): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(96, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer3): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(128, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer4): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(160, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer5): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(192, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer6): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(224, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(224, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "    )\n",
       "    (transition1): _Transition(\n",
       "      (norm): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      (relu): ReLU(inplace)\n",
       "      (conv): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "      (pool): AvgPool2d(kernel_size=2, stride=2, padding=0)\n",
       "    )\n",
       "    (denseblock2): _DenseBlock(\n",
       "      (denselayer1): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(128, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer2): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(160, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer3): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(192, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer4): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(224, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(224, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer5): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer6): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(288, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(288, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer7): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(320, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer8): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(352, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(352, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer9): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(384, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer10): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(416, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(416, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer11): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(448, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(448, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer12): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(480, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(480, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "    )\n",
       "    (transition2): _Transition(\n",
       "      (norm): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      (relu): ReLU(inplace)\n",
       "      (conv): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "      (pool): AvgPool2d(kernel_size=2, stride=2, padding=0)\n",
       "    )\n",
       "    (denseblock3): _DenseBlock(\n",
       "      (denselayer1): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer2): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(288, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(288, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer3): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(320, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer4): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(352, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(352, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer5): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(384, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer6): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(416, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(416, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer7): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(448, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(448, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer8): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(480, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(480, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer9): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer10): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(544, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(544, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer11): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(576, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer12): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(608, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(608, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer13): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(640, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(640, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer14): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(672, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(672, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer15): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(704, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(704, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer16): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(736, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(736, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer17): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(768, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(768, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer18): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(800, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(800, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer19): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(832, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(832, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer20): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(864, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(864, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer21): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(896, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(896, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer22): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(928, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(928, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer23): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(960, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer24): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(992, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(992, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "    )\n",
       "    (transition3): _Transition(\n",
       "      (norm): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      (relu): ReLU(inplace)\n",
       "      (conv): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "      (pool): AvgPool2d(kernel_size=2, stride=2, padding=0)\n",
       "    )\n",
       "    (denseblock4): _DenseBlock(\n",
       "      (denselayer1): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer2): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(544, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(544, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer3): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(576, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer4): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(608, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(608, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer5): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(640, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(640, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer6): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(672, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(672, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer7): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(704, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(704, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer8): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(736, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(736, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer9): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(768, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(768, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer10): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(800, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(800, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer11): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(832, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(832, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer12): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(864, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(864, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer13): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(896, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(896, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer14): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(928, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(928, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer15): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(960, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "      (denselayer16): _DenseLayer(\n",
       "        (norm1): BatchNorm2d(992, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu1): ReLU(inplace)\n",
       "        (conv1): Conv2d(992, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (norm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        (relu2): ReLU(inplace)\n",
       "        (conv2): Conv2d(128, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      )\n",
       "    )\n",
       "    (norm5): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "  )\n",
       "  (classifier): Linear(in_features=1024, out_features=1000, bias=True)\n",
       ")"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model = models.densenet121(pretrained=True)\n",
    "model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This model is built out of two main parts, the features and the classifier. The features part is a stack of convolutional layers and overall works as a feature detector that can be fed into a classifier. The classifier part is a single fully-connected layer `(classifier): Linear(in_features=1024, out_features=1000)`. This layer was trained on the ImageNet dataset, so it won't work for our specific problem. That means we need to replace the classifier, but the features will work perfectly on their own. In general, I think about pre-trained networks as amazingly good feature detectors that can be used as the input for simple feed-forward classifiers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Freeze parameters so we don't backprop through them\n",
    "for param in model.parameters():\n",
    "    param.requires_grad = False\n",
    "\n",
    "from collections import OrderedDict\n",
    "classifier = nn.Sequential(OrderedDict([\n",
    "                          ('fc1', nn.Linear(1024, 512)),\n",
    "                          ('relu1', nn.ReLU()),\n",
    "                          ('fc2', nn.Linear(512,256)),\n",
    "                          ('relu2', nn.ReLU()),\n",
    "                          ('fc3', nn.Linear(256, 2)),\n",
    "                          ('output', nn.LogSoftmax(dim=1))\n",
    "                          ]))\n",
    "    \n",
    "model.classifier = classifier"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With our model built, we need to train the classifier. However, now we're using a **really deep** neural network. If you try to train this on a CPU like normal, it will take a long, long time. Instead, we're going to use the GPU to do the calculations. The linear algebra computations are done in parallel on the GPU leading to 100x increased training speeds. It's also possible to train on multiple GPUs, further decreasing training time.\n",
    "\n",
    "PyTorch, along with pretty much every other deep learning framework, uses [CUDA](https://developer.nvidia.com/cuda-zone) to efficiently compute the forward and backwards passes on the GPU. In PyTorch, you move your model parameters and other tensors to the GPU memory using `model.to('cuda')`. You can move them back from the GPU with `model.to('cpu')` which you'll commonly do when you need to operate on the network output outside of PyTorch. As a demonstration of the increased speed, I'll compare how long it takes to perform a forward and backward pass with and without a GPU."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Device = cpu; Time per batch: 5.711 seconds\n",
      "Device = cuda; Time per batch: 0.009 seconds\n"
     ]
    }
   ],
   "source": [
    "# Try to replace with just ['cuda'] if you are using GPU \n",
    "\n",
    "for device in ['cpu', 'cuda']:\n",
    "\n",
    "    criterion = nn.NLLLoss()\n",
    "    # Only train the classifier parameters, feature parameters are frozen\n",
    "    optimizer = optim.Adam(model.classifier.parameters(), lr=0.001)\n",
    "\n",
    "    model.to(device)\n",
    "\n",
    "    for ii, (inputs, labels) in enumerate(trainloader):\n",
    "\n",
    "        # Move input and label tensors to the GPU\n",
    "        inputs, labels = inputs.to(device), labels.to(device)\n",
    "\n",
    "        start = time.time()\n",
    "\n",
    "        outputs = model.forward(inputs)\n",
    "        loss = criterion(outputs, labels)\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "\n",
    "        if ii==3:\n",
    "            break\n",
    "        \n",
    "    print(f\"Device = {device}; Time per batch: {(time.time() - start)/3:.3f} seconds\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can write device agnostic code which will automatically use CUDA if it's enabled like so:\n",
    "```python\n",
    "# at beginning of the script\n",
    "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
    "\n",
    "...\n",
    "\n",
    "# then whenever you get a new Tensor or Module\n",
    "# this won't copy if they are already on the desired device\n",
    "input = data.to(device)\n",
    "model = MyModule(...).to(device)\n",
    "```\n",
    "\n",
    "From here, I'll let you finish training the model. The process is the same as before except now your model is much more powerful. You should get better than 95% accuracy easily.\n",
    "\n",
    "**Train a pretrained models to classify the cat and dog images. Continue with the DenseNet model, or try ResNet, it's also a good model to try out first. Make sure you are only training the classifier and the parameters for the features part are frozen.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/lib/python3.6/site-packages/torchvision-0.2.1-py3.6.egg/torchvision/models/densenet.py:212: UserWarning: nn.init.kaiming_normal is now deprecated in favor of nn.init.kaiming_normal_.\n"
     ]
    }
   ],
   "source": [
    "# Use GPU if it's available\n",
    "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "\n",
    "model = models.densenet121(pretrained=True)\n",
    "\n",
    "# Freeze parameters so we don't backprop through them\n",
    "for param in model.parameters():\n",
    "    param.requires_grad = False\n",
    "    \n",
    "model.classifier = nn.Sequential(nn.Linear(1024, 512),\n",
    "                                 nn.ReLU(),\n",
    "                                 nn.Dropout(0.2),\n",
    "                                 nn.Linear(512, 256),\n",
    "                                 nn.ReLU(),\n",
    "                                 nn.Dropout(0.1),\n",
    "                                 nn.Linear(256, 2),\n",
    "                                 nn.LogSoftmax(dim=1))\n",
    "\n",
    "criterion = nn.NLLLoss()\n",
    "\n",
    "# Only train the classifier parameters, feature parameters are frozen\n",
    "optimizer = optim.Adam(model.classifier.parameters(), lr=0.003)\n",
    "\n",
    "model.to(device);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Device cuda..Epoch 1/1.. Step 5.. Train loss: 1.156.. Test loss: 0.592.. Test accuracy: 0.515\n",
      "Device cuda..Epoch 1/1.. Step 10.. Train loss: 0.600.. Test loss: 0.406.. Test accuracy: 0.967\n",
      "Device cuda..Epoch 1/1.. Step 15.. Train loss: 0.378.. Test loss: 0.120.. Test accuracy: 0.973\n",
      "Device cuda..Epoch 1/1.. Step 20.. Train loss: 0.296.. Test loss: 0.103.. Test accuracy: 0.964\n",
      "Device cuda..Epoch 1/1.. Step 25.. Train loss: 0.171.. Test loss: 0.068.. Test accuracy: 0.975\n",
      "Device cuda..Epoch 1/1.. Step 30.. Train loss: 0.241.. Test loss: 0.150.. Test accuracy: 0.947\n",
      "Device cuda..Epoch 1/1.. Step 35.. Train loss: 0.305.. Test loss: 0.093.. Test accuracy: 0.962\n",
      "Device cuda..Epoch 1/1.. Step 40.. Train loss: 0.190.. Test loss: 0.075.. Test accuracy: 0.975\n",
      "Device cuda..Epoch 1/1.. Step 45.. Train loss: 0.213.. Test loss: 0.063.. Test accuracy: 0.980\n",
      "Device cuda..Epoch 1/1.. Step 50.. Train loss: 0.144.. Test loss: 0.069.. Test accuracy: 0.975\n",
      "Device cuda..Epoch 1/1.. Step 55.. Train loss: 0.139.. Test loss: 0.081.. Test accuracy: 0.971\n",
      "Device cuda..Epoch 1/1.. Step 60.. Train loss: 0.260.. Test loss: 0.050.. Test accuracy: 0.982\n",
      "Device cuda..Epoch 1/1.. Step 65.. Train loss: 0.163.. Test loss: 0.051.. Test accuracy: 0.982\n",
      "Device cuda..Epoch 1/1.. Step 70.. Train loss: 0.202.. Test loss: 0.056.. Test accuracy: 0.981\n",
      "Device cuda..Epoch 1/1.. Step 75.. Train loss: 0.247.. Test loss: 0.057.. Test accuracy: 0.983\n",
      "Device cuda..Epoch 1/1.. Step 80.. Train loss: 0.185.. Test loss: 0.057.. Test accuracy: 0.983\n",
      "Device cuda..Epoch 1/1.. Step 85.. Train loss: 0.211.. Test loss: 0.058.. Test accuracy: 0.980\n",
      "Device cuda..Epoch 1/1.. Step 90.. Train loss: 0.169.. Test loss: 0.050.. Test accuracy: 0.983\n",
      "Device cuda..Epoch 1/1.. Step 95.. Train loss: 0.161.. Test loss: 0.048.. Test accuracy: 0.983\n",
      "Device cuda..Epoch 1/1.. Step 100.. Train loss: 0.172.. Test loss: 0.044.. Test accuracy: 0.984\n",
      "Device cuda..Epoch 1/1.. Step 105.. Train loss: 0.144.. Test loss: 0.041.. Test accuracy: 0.985\n",
      "Device cuda..Epoch 1/1.. Step 110.. Train loss: 0.186.. Test loss: 0.044.. Test accuracy: 0.984\n",
      "Device cuda..Epoch 1/1.. Step 115.. Train loss: 0.189.. Test loss: 0.044.. Test accuracy: 0.984\n",
      "Device cuda..Epoch 1/1.. Step 120.. Train loss: 0.148.. Test loss: 0.045.. Test accuracy: 0.984\n",
      "Device cuda..Epoch 1/1.. Step 125.. Train loss: 0.202.. Test loss: 0.064.. Test accuracy: 0.978\n",
      "Device cuda..Epoch 1/1.. Step 130.. Train loss: 0.245.. Test loss: 0.082.. Test accuracy: 0.970\n",
      "Device cuda..Epoch 1/1.. Step 135.. Train loss: 0.141.. Test loss: 0.065.. Test accuracy: 0.977\n",
      "Device cuda..Epoch 1/1.. Step 140.. Train loss: 0.220.. Test loss: 0.083.. Test accuracy: 0.968\n",
      "Device cuda..Epoch 1/1.. Step 145.. Train loss: 0.290.. Test loss: 0.094.. Test accuracy: 0.971\n",
      "Device cuda..Epoch 1/1.. Step 150.. Train loss: 0.246.. Test loss: 0.078.. Test accuracy: 0.979\n",
      "Device cuda..Epoch 1/1.. Step 155.. Train loss: 0.160.. Test loss: 0.098.. Test accuracy: 0.964\n",
      "Device cuda..Epoch 1/1.. Step 160.. Train loss: 0.211.. Test loss: 0.047.. Test accuracy: 0.985\n",
      "Device cuda..Epoch 1/1.. Step 165.. Train loss: 0.231.. Test loss: 0.043.. Test accuracy: 0.986\n",
      "Device cuda..Epoch 1/1.. Step 170.. Train loss: 0.154.. Test loss: 0.053.. Test accuracy: 0.981\n",
      "Device cuda..Epoch 1/1.. Step 175.. Train loss: 0.158.. Test loss: 0.057.. Test accuracy: 0.980\n",
      "Device cuda..Epoch 1/1.. Step 180.. Train loss: 0.188.. Test loss: 0.041.. Test accuracy: 0.983\n",
      "Device cuda..Epoch 1/1.. Step 185.. Train loss: 0.135.. Test loss: 0.041.. Test accuracy: 0.983\n",
      "Device cuda..Epoch 1/1.. Step 190.. Train loss: 0.137.. Test loss: 0.057.. Test accuracy: 0.979\n",
      "Device cuda..Epoch 1/1.. Step 195.. Train loss: 0.128.. Test loss: 0.042.. Test accuracy: 0.983\n",
      "Device cuda..Epoch 1/1.. Step 200.. Train loss: 0.118.. Test loss: 0.044.. Test accuracy: 0.982\n",
      "Device cuda..Epoch 1/1.. Step 205.. Train loss: 0.143.. Test loss: 0.041.. Test accuracy: 0.984\n",
      "Device cuda..Epoch 1/1.. Step 210.. Train loss: 0.166.. Test loss: 0.042.. Test accuracy: 0.983\n",
      "Device cuda..Epoch 1/1.. Step 215.. Train loss: 0.133.. Test loss: 0.049.. Test accuracy: 0.980\n",
      "Device cuda..Epoch 1/1.. Step 220.. Train loss: 0.169.. Test loss: 0.055.. Test accuracy: 0.976\n",
      "Device cuda..Epoch 1/1.. Step 225.. Train loss: 0.146.. Test loss: 0.046.. Test accuracy: 0.984\n",
      "Device cuda..Epoch 1/1.. Step 230.. Train loss: 0.173.. Test loss: 0.040.. Test accuracy: 0.985\n",
      "Device cuda..Epoch 1/1.. Step 235.. Train loss: 0.134.. Test loss: 0.054.. Test accuracy: 0.978\n",
      "Device cuda..Epoch 1/1.. Step 240.. Train loss: 0.148.. Test loss: 0.038.. Test accuracy: 0.985\n",
      "Device cuda..Epoch 1/1.. Step 245.. Train loss: 0.161.. Test loss: 0.038.. Test accuracy: 0.986\n",
      "Device cuda..Epoch 1/1.. Step 250.. Train loss: 0.138.. Test loss: 0.064.. Test accuracy: 0.976\n",
      "Device cuda..Epoch 1/1.. Step 255.. Train loss: 0.167.. Test loss: 0.046.. Test accuracy: 0.982\n",
      "Device cuda..Epoch 1/1.. Step 260.. Train loss: 0.133.. Test loss: 0.041.. Test accuracy: 0.983\n",
      "Device cuda..Epoch 1/1.. Step 265.. Train loss: 0.156.. Test loss: 0.042.. Test accuracy: 0.982\n",
      "Device cuda..Epoch 1/1.. Step 270.. Train loss: 0.172.. Test loss: 0.040.. Test accuracy: 0.984\n",
      "Device cuda..Epoch 1/1.. Step 275.. Train loss: 0.112.. Test loss: 0.048.. Test accuracy: 0.980\n",
      "Device cuda..Epoch 1/1.. Step 280.. Train loss: 0.144.. Test loss: 0.040.. Test accuracy: 0.986\n",
      "Device cuda..Epoch 1/1.. Step 285.. Train loss: 0.160.. Test loss: 0.041.. Test accuracy: 0.983\n",
      "Device cuda..Epoch 1/1.. Step 290.. Train loss: 0.134.. Test loss: 0.064.. Test accuracy: 0.975\n",
      "Device cuda..Epoch 1/1.. Step 295.. Train loss: 0.162.. Test loss: 0.041.. Test accuracy: 0.985\n",
      "Device cuda..Epoch 1/1.. Step 300.. Train loss: 0.145.. Test loss: 0.050.. Test accuracy: 0.981\n",
      "Device cuda..Epoch 1/1.. Step 305.. Train loss: 0.127.. Test loss: 0.055.. Test accuracy: 0.979\n",
      "Device cuda..Epoch 1/1.. Step 310.. Train loss: 0.142.. Test loss: 0.037.. Test accuracy: 0.987\n",
      "Device cuda..Epoch 1/1.. Step 315.. Train loss: 0.207.. Test loss: 0.038.. Test accuracy: 0.984\n",
      "Device cuda..Epoch 1/1.. Step 320.. Train loss: 0.169.. Test loss: 0.105.. Test accuracy: 0.960\n",
      "Device cuda..Epoch 1/1.. Step 325.. Train loss: 0.243.. Test loss: 0.064.. Test accuracy: 0.984\n",
      "Device cuda..Epoch 1/1.. Step 330.. Train loss: 0.206.. Test loss: 0.059.. Test accuracy: 0.982\n",
      "Device cuda..Epoch 1/1.. Step 335.. Train loss: 0.127.. Test loss: 0.068.. Test accuracy: 0.978\n",
      "Device cuda..Epoch 1/1.. Step 340.. Train loss: 0.149.. Test loss: 0.039.. Test accuracy: 0.983\n",
      "Device cuda..Epoch 1/1.. Step 345.. Train loss: 0.218.. Test loss: 0.038.. Test accuracy: 0.983\n",
      "Device cuda..Epoch 1/1.. Step 350.. Train loss: 0.164.. Test loss: 0.040.. Test accuracy: 0.982\n"
     ]
    }
   ],
   "source": [
    "traininglosses = []\n",
    "testinglosses = []\n",
    "testaccuracy = []\n",
    "totalsteps = []\n",
    "epochs = 1\n",
    "steps = 0\n",
    "running_loss = 0\n",
    "print_every = 5\n",
    "for epoch in range(epochs):\n",
    "    for inputs, labels in trainloader:\n",
    "        steps += 1\n",
    "        # Move input and label tensors to the default device\n",
    "        inputs, labels = inputs.to(device), labels.to(device)\n",
    "        \n",
    "        optimizer.zero_grad()\n",
    "        \n",
    "        logps = model.forward(inputs)\n",
    "        loss = criterion(logps, labels)\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "\n",
    "        running_loss += loss.item()\n",
    "        \n",
    "        if steps % print_every == 0:\n",
    "            test_loss = 0\n",
    "            accuracy = 0\n",
    "            model.eval()\n",
    "            with torch.no_grad():\n",
    "                for inputs, labels in testloader:\n",
    "                    inputs, labels = inputs.to(device), labels.to(device)\n",
    "                    logps = model.forward(inputs)\n",
    "                    batch_loss = criterion(logps, labels)\n",
    "                    \n",
    "                    test_loss += batch_loss.item()\n",
    "                    \n",
    "                    # Calculate accuracy\n",
    "                    ps = torch.exp(logps)\n",
    "                    top_p, top_class = ps.topk(1, dim=1)\n",
    "                    equals = top_class == labels.view(*top_class.shape)\n",
    "                    accuracy += torch.mean(equals.type(torch.FloatTensor)).item()\n",
    "            \n",
    "            traininglosses.append(running_loss/print_every)\n",
    "            testinglosses.append(test_loss/len(testloader))\n",
    "            testaccuracy.append(accuracy/len(testloader))\n",
    "            totalsteps.append(steps)\n",
    "            print(f\"Device {device}..\"\n",
    "                  f\"Epoch {epoch+1}/{epochs}.. \"\n",
    "                  f\"Step {steps}.. \"\n",
    "                  f\"Train loss: {running_loss/print_every:.3f}.. \"\n",
    "                  f\"Test loss: {test_loss/len(testloader):.3f}.. \"\n",
    "                  f\"Test accuracy: {accuracy/len(testloader):.3f}\")\n",
    "            running_loss = 0\n",
    "            model.train()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAusAAAH0CAYAAACEkWPuAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4wLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvpW3flQAAIABJREFUeJzs3Xl8VPW9//HXNzOZSTKZkLBI2CJrAFEugiKCEhDBpRQpeKtVab2utb2tWm2tSy9ab9Hb2nuxWhW1Fa33196KbYGoFZRVLVpWN3bCEnYICdm3+f7+mGQyk3USJjNB3s/HI4+ZzDlz5jsnmeQ9n/M53zHWWkREREREpOOJi/UARERERESkcQrrIiIiIiIdlMK6iIiIiEgHpbAuIiIiItJBKayLiIiIiHRQCusiIiIiIh2UwrqIiIiISAelsC4iIiIi0kEprIuIiIiIdFAK6yIiIiIiHZTCuoiIiIhIB6WwLiIiIiLSQSmsi4iIiIh0UArrIiIiIiIdlMK6iIiIiEgHFZGwboy51hjzjDFmtTHmpDHGGmNeb+U2uhhjbjPG/NUYs8MYU2qMKTDGfGCMudUYozcWIiIiInJGcUZoO48A/wIUAbnAkDZs41+B54GDwHJgL9AdmAG8DFxljPlXa61t6yCNMTlACrC7rdsQEREREQlDX+CktbbfqWzEnEL2rduIMRPxh/QdQBb+sP2/1tqbWrGNywAP8Ja11hd0ezrwCdAHuNZa++YpjPN4YmJi56FDh7Z1E40qLCwEwOv1RnS74qf92760f9uf9nH70v5tX9q/7Uv7t/3Fah9v3ryZ0tLSPGttl1PZTkQq69ba5bXXjTFt3cayJm4/ZIx5AfgFMAFoc1gHdg8dOrTzunXrTmETDa1YsQKACRMmRHS74qf92760f9uf9nH70v5tX9q/7Uv7t/3Fah+PGjWK9evX7z7V7ZwufeCVNZdVMR2FiIiIiEgURaQNJmSDxkygDW0wzWzPCWwAzgWutNa+G8Z9miqdDxk0aFDSiy++eKrDCqFDWO1L+7d9af+2P+3j9qX92760f9uX9m/7i9U+vuOOO9i+fft6a+2oU9nO6VBZfxJ/UH87nKAuIiIiIvJVEanZYNqFMeaHwH3AFmBWuPdr6h2MMWad1+sdGemeJfWbtS/t3/al/dv+tI/bl/Zv+9L+bV/av+0vVvs4UpX8DltZN8Z8H3ga+BKYaK3Ni/GQRERERESiqkOGdWPMPcCzwOf4g/qhGA9JRERERCTqOlxYN8Y8APwPsBF/UD8S4yGJiIiIiMRE1MO6MSbeGDPEGDOgkWU/w39C6TpgkrX2WLTHJyIiIiLSUUTkBFNjzHRges236TWXFxtj5tdcP2atvb/mei9gM7AH/8ew1m7jO8DPgWpgNfDDRj5gabe1dn79G0VEREREvooiNRvMCOA79W7rX/MF/mB+P83rV3PpAO5pYp2VwPw2jE9ERERE5LQTkTYYa+2j1lrTzFffoHV3178tzG0Ya+2ESIxXREREROR00OFOMBURERERET+FdRERERGRDkphXURERESkg1JYFxERERHpoBTWo8TnsxSXV1FZ7Yv1UERERETkNBGpqRulGbe/tpalXx4G4JWbL2TikLNiPCIREREROR2osh4F8Y66D3cqrqiK4UhERERE5HSisB4FifF1BzBKKqpjOBIREREROZ0orEeBx+0IXC8pV2VdRERERMKjsB4Fia6gsF6pyrqIiIiIhEdhPQo8rqA2mHKFdREREREJj8J6FCQFV9bVsy4iIiIiYVJYj4Kk4Mq6ZoMRERERkTAprEdBcGW9WJV1EREREQmTwnoUBIf1UlXWRURERCRMCutR4HHXtcEU6wRTEREREQmTwnoUaOpGEREREWkLhfUoCJ26UW0wIiIiIhIehfUo0NSNIiIiItIWCutREBrWVVkXERERkfAorEdB6DzrqqyLiIiISHgU1qMgIT4OY/zXy6t8VPtsbAckIiIiIqcFhfUoMMaQFK9WGBERERFpHYX1KElyqxVGRERERFpHYT1KNCOMiIiIiLSWwnqUBJ9kWqy51kVEREQkDArrURJcWS/Vp5iKiIiISBgU1qMkOKyrsi4iIiIi4VBYj5KQyrp61kVEREQkDArrUeIJ7llXWBcRERGRMCisR0liSGVdbTAiIiIi0jKF9SjxuFVZFxEREZHWUViPksR4zbMuIiIiIq2jsB4lHndQWNdsMCIiIiISBoX1KEkMOsG0RPOsi4iIiEgYFNajxONSZV1EREREWkdhPUqC51lXz7qIiIiIhENhPUqSgttgFNZFREREJAwK61ESWllXG4yIiIiItExhPUpUWRcRERGR1lJYjxL1rIuIiIhIaymsR0mSW20wIiIi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YIJPLo1VZR38c6P/MuuXDO9a1/ee5Ezi/gvu582vv6mgLiIiIhJlqqxHWVIj86wHV9ZjGdbBP5/qc5c/xwubXiA+Lp5Z58yiW1K3mI5JRERE5EylsB5lSY18gmlhZd185bEO6+CfrumB0Q/EehgiIiIiZzy1wURZcGW9tLZnvSL2PesiIiIi0vEorEdZ8DzrxRUdZzYYEREREel4FNajLDGoDaa0sdlg4lVZFxERERE/hfUo8wS1wRR3oHnWRURERKTjUViPssTgnvVGPsE02aWwLiIiIiJ+CutR5nLE4YwzAFRWWyqqfB1mnnURERFxOk6hAAAgAElEQVQR6VgU1qPMGBNSXS+pqAppg1HPuoiIiIjUUliPAU+9TzFVz7qIiIiINEZhPQbqf4ppyGwwmmddRERERGoorMdAkjs4rFerZ11EREREGqWwHgNJ8XVtMMXl1aGzwSisi4iIiEgNhfUYCK6sF5WXUVZdBkCciSPRmRirYYmIiIhIB6OwHgPBPet5pYWB6554D8aYWAxJRERERDoghfUYSAqaDSa/rC6sqwVGRERERIIprMeAJ6iyXlAeWlkXEREREamlsB4DiUGV9ZPlmglGRERERBqnsB4DwZX1woqgyrrmWBcRERGRIArrMZAYFNaLgqZt9MZ7YzEcEREREemgFNZjwOOua4MpCf70UvWsi4iIiEgQhfUYCJ66saRaH4gkIiIiIo1TWI+B4Kkby6qCKuvqWRcRERGRIArrMRBcWS+rLglcV2VdRERERIIprMdAcFivsArrIiIiItI4hfUYCG6DqfSVBq7rBFMRERERCaawHgPBlfUq6sJ6skuVdRERERGpo7AeA8FhvTo4rKsNRkRERESCKKzHQPA86z5TFriusC4iIiIiwRTWY8DtjMOYmm/i6sK6etZFREREJJjCegwYY/DUnGRqgsK6etZFREREJJjCeowkuhxANSauEgCDIdGZGNtBiYiIiEiHorAeIx6XA+LK676P9xBn9OMQERERkTpKhzGS6HJigsK6WmBEREREpD6F9RjxuBwYR1BY10wwIiIiIlKPwnqMJLocISeXaiYYEREREalPYT1GPC5nyLSNqqyLiIiISH0K6zGSVK8NRpV1EREREalPYT1GktwOzbEuIiIiIs1SWI+RJJczZOpGtcGIiIiISH0K6zGSVO8EU4V1EREREalPYT1G1LMuIiIiIi1RWI+RJJdTPesiIiIi0iyF9RhJcjlCpm5UZV1ERERE6lNYjxF/ZV0nmIqIiIhI0yIW1o0xvY0xvzfGHDDGlBtjdhtj5hpj0lq5nUuMMQtr7l9mjNlrjHnbGHNlpMbaEahnXURERERaEpGwbowZAKwD/g34BPgfYBdwN/APY0yXMLdzF7AamFRz+T/ASiALeMcY83AkxtsReNyhbTBelzeGoxERERGRjsgZoe08B5wF/NBa+0ztjcaY/wbuBX4BfLe5DRhj4oEngDJglLV2a9CyOcAG4GFjzFPW2vImNnPaSIwPbYNRZV1ERERE6jvlyroxpj8wBdgN/Lbe4tlAMTDLGNNSGu0MdAK2BQd1AGvtZmAbkAh8JZq7PfU/wVQ96yIiIiJSTyTaYC6ruVxirfUFL7DWFgIfAknAmBa2cwQ4CmQaYwYFLzDGZAKDgI3W2uMRGHPMueLBOCoC3yfFJ8VwNCIiIiLSEUWiDWZwzeW2JpZvx195zwTeb2oj1lprjPk+8DqwzhjzV+AA0Av4BvAFcH04AzLGrGti0ZDCwkJWrFgRzmbCVlhYCNCq7Z6oKA5ct9VuVq1cFdExfZW0Zf9K+LR/25/2cfvS/m1f2r/tS/u3/cVqH9c+7qmKRFjvVHNZ0MTy2ttTW9qQtfYNY8wB4I/At4MWHQZewX/S6ldCtalrgbE+Nz5riTMmhiMSERERkY4mUieYNqc2gdoWVzTmJuAl4C/A48Ae4GzgZ8Cz+GeF+WZL27HWjmpi++u8Xu/ICRMmhDXwcNW+U2vNdref2A6L/NetL4GLxl6Kxx2NH8fppy37V8Kn/dv+tI/bl/Zv+9L+bV/av+0vVvvY643MTH+R6FmvrZx3amJ5Sr31GlXTl/57/O0us6y1W6y1pdbaLcAs/FND/qsxZsKpDzn2iivr2mCoTqC4oip2gxERERGRDikSYb125pbMJpbXnizaVE97rSlAPLCykRNVfUBtU3ejVfPTTVFlUeC69bkpraiO4WhEREREpCOKRFhfXnM5xRgTsj1jjBcYB5QCa1rYjrvmslsTy2tvr2hi+WklNKwnUFyusC4iIiIioU45rFtrdwJLgL7A9+stfgzwAK9ZawN9H8aYIcaYIfXWXV1zea0xZnjwAmPMCOBa/H3vy051zB1BcfBsMD43pZVqgxERERGRUJE6o/F7wEfAb4wxk4DNwEXARPztLw/XW39zzWVg+hNr7SfGmFeAfwP+WTN14x78bwKmAy5grrX2iwiNOaaCK+tUu1VZFxEREZEGIhLWrbU7jTEXAD8HrgSuBg4CvwEes9bmhbmpW/H3pt8MXAF4gZPAB8BL1to/RWK8HUH9NpgS9ayLiIiISD0RmyvQWrsPf1U8nHUbnVDcWmuB+TVfX2lFFfXDutpgRERERCRUJE4wlTYImbrR51ZlXUREREQaUFiPkZA2mGpV1kVERESkIYX1GAmurFtV1kVERESkEQrrMaITTEVERESkJQrrMRJ8gqm/Z11tMCIiIiISSmE9Rhr0rGuedRERERGpR2E9RkJ71tUGIyIiIiINKazHgM/66k3d6KJYbTAiIiIiUo/CegyUVJYErttqFxBHqSrrIiIiIlKPwnoM1J8JBqBYYV1ERERE6lFYj4H6c6wDlKoNRkRERETqUViPgcKKwrpvVFkXERERkSYorMdASGW92h/W1bMuIiIiIvUprMdAaM+6vw2muKIKa22shiQiIiIiHZDCegwEV9bjrL+ybi2UV/liNSQRERER6YAU1mOgqKKusu40iYHrxeU6yVRERERE6jhjPYAzUXBlPd4kBa6XVFTTJRYDEhGRrzSfz0deXh6FhYWUl5e3qu0yKcn/f2rz5s3tNbwzmvZv+4vEPjbG4Ha78Xq9dO7cmbi46NW7FdZjILhn3R1XV1kv0UmmIiISYT6fj3379lFSUtLyyo2oDTrSPrR/218k9rG1lrKyMsrKyiguLqZPnz5RC+wK6zEQEtYdnsD1Es21LiIiEZaXl0dJSQlOp5P09HQ8Hk+rQkZhoX+6Ya/X215DPKNp/7a/SOxjn89HcXExhw4doqSkhLy8PLp27RqpITZLPesxENyznhgS1lVZFxGRyKoNKunp6Xi93qgevhf5qoiLi8Pr9ZKeng7Uva6i8thReyQJCO5ZT3SG9qyLiIhEUnl5OQAej6eFNUWkJbWvo9rXVTQorMdAcBuMJz45cF1tMCIiEmm1J5Oqoi5y6owxAFH9bBy9cmMguLLuiVcbjIiIiMjpoDasR5PCegwEV9a9rrrKuuZZFxEREZFgCusxUFxRV1lPcdeF9VJV1kVEREQkiMJ6lPmsL6Sy3sldN41QscK6iIjIV1ZRURHGGKZOnRrrochpRGE9ykqrSrH4T0pIdCaS7HYFlukEUxERkcgzxrTqa/78+bEecptlZ2frDcFXjD4UKcqC51hPjk/G46r7EegEUxERkcibPXt2g9vmzp1LQUEBd999N6mpqSHLRowY0S7j8Hg8bN68meTk5JZXFqmhsB5l9WeCSXQ5At+rsi4iIhJ5jz76aIPb5s+fT0FBAffccw99+/aNyjiMMQwZMiQqjyVfHWqDibLgfvXk+GQ87uCwrsq6iIhIR3HBBReQnJxMaWkpjzzyCAMHDsTlcvHv//7vABw/fpwnn3ySrKwsevbsicvlonv37sycOZP169c32F5TPesPP/wwxhjWrl3L//7v/zJq1CgSExPp2rUrs2bN4siRI+32HKurq/nNb37DyJEj8Xg8JCcnM2bMGH7/+983uv7777/PVVddRa9evXC73fTo0YNx48bxX//1XyHrHThwgLvvvpvMzEySkpJIS0tj6NCh3Hrrrezbt6/dns9XkSrrURbygUguD4nxQW0w5QrrIiIiHYnP52Pq1Kls3bqVK664gi5dunD22WcDsGHDBmbPns2ECRO45ppr6NSpEzk5OSxatIjs7GyWLl3K+PHjw36sX/7yl2RnZ3PNNdcwceJEPvzwQ15//XU+//xz1q5di8PhaHkjrXxuM2fOZOHChfTr148777yT6upq/vKXv3DrrbeyZs0aXnzxxcD6b775Jtdeey1dunRh2rRppKenc+zYMb788kvmzZvHAw88AMDJkye56KKLOHDgAFOmTGH69OlUVlayZ88eFixYwKxZs+jTp09En8tXmcJ6lAX3rHvjvaGV9Uq1wYiIiHQkpaWlFBYW8vnnnzfobR85ciSHDh0iLS0t5PadO3dy0UUXcd999/HPf/4z7Md6//332bhxI5mZmYD/UzKnT5/OokWLePfdd7n66qtP/QkF+d3vfsfChQsZO3Ys7733HomJiQA8/vjjjB07lpdeeompU6cybdo0gEBwX7NmDQMHDgzZ1rFjxwLX33rrLXJzc3nkkUd4/PHHQ9YrKyujqkp5pzUU1qOsfs96UnDPuirrIiISZX1/+lashxC23U9+LSaP+8QTTzQI6gCdO3dudP0BAwYwbdo0XnnlFY4fP06XLl3Cepwf//jHgaAO/h732267jUWLFvHJJ59EPKzXtrr86le/CgR1gJSUFH7xi18wffp0Xn755UBYrx1TQkJCg2117dq1wW3B26zV2H2leepZj7KQnnVXMkmaDUZERKRDGz16dJPLli9fzowZM+jduzculysw/eMrr7wC+Hu3w3XBBRc0uK22XeTEiROtHHXLNmzYQEJCAhdffHGDZZdddllgnVo33ngj1lpGjBjB97//fRYsWMDBgwcb3Hfy5Ml069aNn/3sZ0ydOpXf/va3bNy4EZ/PF/HncCZQZT3KQnrW61XWizUbjIiISIeSlJSE1+ttdNnrr7/Ot7/9bZKTk5k8eTL9+vXD4/FgjGHJkiX84x//oLy8POzHaqx673T6o1p1dWQLemVlZZSXl9O3b1+MMQ2We71ePB4P+fn5gdtqn+vcuXOZN28ezz33HABjxowJnGgL/ir7xx9/zKOPPkp2djZvveU/etO9e3d++MMf8sADD0S8//6rTGE9yoor6tpgkuNDK+ulFdVYaxt90YiIiLSHllpLCgsLAZoMrF91zf1PfuSRR/B6vWzYsIH+/fuHLNu+fTv/+Mc/2nt4bZaQkIDb7ebw4cONLi8qKqK4uJhevXqF3D5jxgxmzJhBYWEha9asYdGiRcybN4+rr76azz77LLAf+vXrx6uvvorP5+Pzzz/n/fff59lnn+Xhhx/G4XAETkaVlqkNJsrqV9Zdzjiccf4/BFU+S0W1DhGJiIh0dFVVVezZs4cRI0Y0COqVlZUdOqjXGjFiBKWlpXz88ccNli1btgzwn0TbGK/Xy+TJk3nmmWe49957KSkpYenSpQ3Wi4uLY/jw4dx7771kZ2cD8Le//S2Cz+KrT2E9yoJPME2O93+CWXArTKn61kVERDo8p9NJr169+OKLL0JmQvH5fDz44IPk5OTEcHThueWWWwD4yU9+EtKuU1hYyCOPPALArbfeGrh96dKljbb11Fbnk5KSANi4cSO5ubktrifhURtMlBVWFgauJ7v8Yd3jdnKyzN+vXlxRTap+h0VERDq8e++9l/vvv5/hw4czY8YM4uLiWLlyJbt37+aqq67inXfeidnYNm3axM0339zosszMTB566CFuu+02Fi9eTHZ2Nueeey7Tpk0LzLO+b98+brnlFq655prA/e666y5OnDhBVlYWffv2xeFw8PHHH7N69WoyMzP5xje+AUB2djazZ8/mkksuYfDgwXTt2pU9e/awcOFCHA4H999/fzR2wVeGwnqU1e9ZB0gMqazrJFMREZHTwY9+9COSk5N59tln+f3vf4/H42HChAn8+c9/5qWXXoppWM/NzeXVV19tdNm4ceN46KGHiIuL469//SvPPvssr776Ks8//zzGGIYNG8Z//Md/hFTVAWbPns3ixYtZv349S5YsweFwkJGRwaOPPsoPfvADkpP9uWbatGkcPXqU1atX85e//IWioiJ69OjB17/+de67775GZ72RpimsR1n9nnUAT9BJpsWaa11ERKTd7d69u8V11q5d2+xyYwx33nknd955Z4NlTz31FE899VTIbcnJyVhrG6z7i1/8gt/85jeNPsa5557b6H2aMnXq1Fat73Q6ueeee7jnnntaXHfWrFnMmjWrxfWGDx/O008/HfYYpHnqWY+ykJ51V8PKuuZaFxEREZFaCutRFvKhSDVtMJ6QsK42GBERERHxU1iPImttSGU9Kd5/Jqk+xVREREREGqOwHkWlVaX4rH8e9QRHAvFx8UDo1I2qrIuIiIhILYX1KAppganpV4f6YV2VdRERERHxU1iPosb61QGS3GqDEREREZGGFNajKHiO9dppGwGS4tUGIyIiIiINKaxHUTiVdc2zLiIiIiK1FNajKHgmmJDKesgnmCqsi4iIiIifwnoUhXOCabHaYERERESkhsJ6FIV8emlwG0zQPOuqrIuIiIhILYX1KCqsKAxcD26D8aiyLiIiIiKNUFiPopDKelAbTKJ61kVERESkEQrrUdTUbDCe4NlgFNZFREREpIbCehQ1Nc96Yrwq6yIiIu3FGNOqr/nz57freIqKijDGMHXq1Fbf99prr8UYw4IFC9phZNIROVteJTzGmN7Az4ErgS7AQeBvwGPW2hOt3NZ5wI+BicBZQAGwGfidtfa1SI052sKrrKtnXUREJJJmz57d4La5c+dSUFDA3XffTWpqasiyESNGRGtoIi2KSFg3xgwAPsIfrBcCW4DRwN3AlcaYcdba42Fu62bgZaAEyAZ2A6nAucDVwGkb1sOZZ71ElXUREZGIevTRRxvcNn/+fAoKCrjnnnvo27dv1MckEq5ItcE8hz+o/9BaO91a+1Nr7WXA/wCDgV+EsxFjzBj8Qf1zINNae4O19iFr7festeOBWREab0wEV9a9Lm/gutsZR5zxX6+o8lFV7Yv20ERERKQRR48e5f7772fw4MEkJCSQlpbGFVdcwYoVKxqsW1paylNPPcWIESNI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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f80cb6c7048>"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 250,
       "width": 373
      },
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "plt.plot(totalsteps, traininglosses, label='Train Loss')\n",
    "plt.plot(totalsteps, testinglosses, label='Test Loss')\n",
    "plt.plot(totalsteps, testaccuracy, label='Test Accuracy')\n",
    "plt.legend()\n",
    "plt.grid()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "checkpoint = {\n",
    "    'parameters' : model.parameters,\n",
    "    'state_dict' : model.state_dict()\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "torch.save(checkpoint, './catvdog.pth')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
